package edu.hrbu.test.compiler;

import org.apache.ibatis.io.Resources;

import java.io.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * @author 徐登宇
 * @date 2022-11-01 15:37
 */
public class MyLexer {

    // @@ 关键字 | 界符 @@
    public static final String[] keyWordArr = {
            "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const",
            "continue", "default", "do", "double", "else", "enum", "extends", "final", "finally", "float",
            "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native",
            "new", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super",
            "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", "while"
    };
    //界符表(12)
    public static final Character[] delimiterArr = {
            ',', ';', '(', ')',
            '[', ']', '{', '}',
            '.', '@', '"' // 注解的标志也算界符中了
    };
    // 运算符
    public static final Character[] operatorArr = {
            '+', '-', '*', '%', '=', '>', '<' // 只考虑了单个的运算符，像 +=, << 之类的没有考虑
    };



    //关键字（50个）
    public static Set<String> keyWordList = new HashSet<>();
    //界符
    public static Set<Character> delimiterList = new HashSet<>();
    //标识符
    public static Set<String> dentifierList = new HashSet<>();
    //数字
    public static Set<String> digitList = new HashSet<>();
    // 运算符
    public static Set<Character> operatorList = new HashSet<>();


    //@@ 初始化 @@
    public static void init() {
        keyWordList.addAll(Arrays.asList(keyWordArr));
        delimiterList.addAll(Arrays.asList(delimiterArr));
        operatorList.addAll(Arrays.asList(operatorArr));
    }



    //判断是否是：字母
    public static boolean isLetter(char x) { return (x >= 'a' && x <= 'z')||(x >= 'A' && x <= 'Z'); }

    //判断是否是：数字
    public static boolean isDigit(char x) { return x >= '0' && x <= '9'; }

    //判断是否是：界符
    public static boolean isDelimiter(char x) { return delimiterList.contains(x); }

    //判断是否是 运算符
    public static boolean isOperator(char x) { return operatorList.contains(x); }

    public static void doMain() throws IOException {

        Reader in = Resources.getResourceAsReader("in.txt");
        BufferedReader reader = new BufferedReader(in);
        FileWriter out = new FileWriter("out.txt");
        BufferedWriter writer = new BufferedWriter(out);
        String content;
        boolean flag = false;

        //readLine一行一行的读取
        while((content = reader.readLine()) != null) {
            int count = 0;
            while (flag) {
                while (count < content.length()) {
                    if(content.charAt(count)=='*') {
                        count++;
                        if(count< content.length() && content.charAt(count)=='/') {
                            count++;
                            flag = false;
                        }
                    }
                    else count++;
                }
                break;
            }
            while (count < content.length()) {
                if (content.charAt(count) == ' ') {
                    count++;
                }
                else if (isLetter(content.charAt(count)) || content.charAt(count) == '_') {
                    StringBuilder str = new StringBuilder();
                    str.append(content.charAt(count++));
                    while (count < content.length() && (isLetter(content.charAt(count)) || isDigit(content.charAt(count)) || content.charAt(count)=='_')) {
                        str.append(content.charAt(count++));
                    }
                    if(keyWordList.contains(str.toString())) {
                        System.out.println(str);
                        writer.write("(关键字," + str + ")" + "\r\n");
                        continue;
                    }
                    dentifierList.add(str.toString());
                    System.out.println(str);
                    writer.write("(标识符," + str + ")" + "\r\n");

                }
                else if(isOperator(content.charAt(count))) {
                    String str = "";
                    str += content.charAt(count++);
                    System.out.println(str);
                    writer.write("(运算符," + str + ")" + "\r\n");
                }
                else if(isDigit(content.charAt(count))) {
                    StringBuilder str = new StringBuilder();
                    str.append(content.charAt(count++));
                    while(count < content.length() && isDigit(content.charAt(count))) {
                        str.append(content.charAt(count++));
                    }
                    digitList.add(str.toString());
                    System.out.println(str);
                    writer.write("(数字," + str + ")" + "\r\n");
                }
                else if(isDelimiter(content.charAt(count))) {
                    String str = "";
                    str += content.charAt(count);
                    System.out.println(str);
                    writer.write("(界符," + str + ")" + "\r\n");
                    count++;
                }
                else if(content.charAt(count)=='/') {
                    String str = "";
                    str += content.charAt(count);
                    count++;
                    if(content.charAt(count)!='*' && content.charAt(count) !='/') {
                        writer.write("(标识符," + str + ")" + "\r\n");
                    }
                    if(content.charAt(count)=='/') {
                        break;
                    }
                    if(content.charAt(count)=='*') {
                        count++;
                        flag = true;
                        while (count < content.length()) {
                            if(content.charAt(count)=='*') {
                                count++;
                                if(count< content.length() && content.charAt(count)=='/') {
                                    count++;
                                    flag = false;
                                }
                            }
                            else count++;
                        }
                    }
                }
                else {
                    String str = "";
                    str += content.charAt(count);
                    count++;
                    System.out.println(str);
                    writer.write("(其他," + str + ")" + "\r\n");
                }
            }
        }
        reader.close();
        writer.close();
    }

    public static void main(String[] args) throws IOException {
        init();
        doMain();
    }
}
